#ifndef DEALMSGPACKET_H
#define DEALMSGPACKET_H

#include <QObject>
#include <QtWebSockets/QWebSocket>
#include <queue>
#include <memory>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <QVariantMap>
#include <QVariantList>
#include <QTimer>

#ifdef AARCH64
    #include "arm_cppJson/include/json.h"
#else
    #include "cJson/include/json.h"
#endif

class DoDataThread : public QObject{
    Q_OBJECT
public:
    DoDataThread(QObject* parent = nullptr);
    ~DoDataThread();

protected:
    void run();

public:
   void sendMsg(const QString& msg);

private:
    void __initSlots();

signals:
    void onMessage(QString msg);
    void onCallBack(const QString& msg);
    void onCallBinaryBack(const QByteArray& msg);
    void onNetConnect(const bool&);

public slots:
    void onConnected();
    void closeConnection();
    void onTextMessageReceived(QString);
    void doMessage(QString msg);
    void doBinaryMessage(const QByteArray&);

private:
    std::thread* m_Thread = nullptr;
    std::queue<QString> m_MsgQueue;           //前端页面的消息队列
    std::shared_ptr<QWebSocket> m_WebSocket;
    std::mutex m_Mutex;
    std::condition_variable m_Condition;
    bool is_Waiting = true;                   //标记线程是还在运行

    QUrl m_ServerUrl = QUrl("");
    QTimer *m_Timer = nullptr;                         //定时连接websocket服务端
};

/**************************************************************/

/**
 * @brief The MsgControl class
 * 接受页面的数据和处理服务端的返回数据的控制类
 */

class MsgControl : public QObject
{
    Q_OBJECT

    Q_PROPERTY(int startBtnStatus READ getStartBtnStatus WRITE setStartBtnStatus NOTIFY startBtnStatusChanged)
    Q_PROPERTY(QVariantMap errorMsg  READ getErrorMsg WRITE setErrorMsg NOTIFY errorMsgChanged)
    Q_PROPERTY(bool netConnected READ getNetConnected NOTIFY netConnectedChanged)
    Q_PROPERTY(QVariantList fileList READ getFileList WRITE setFileList NOTIFY fileListChanged)
    Q_PROPERTY(QVariantList curFileslist READ getCurFilesList WRITE setCurFilesList NOTIFY curFileslistChanged)
    Q_PROPERTY(QVariantList taskFilesList READ getTaskFilesList WRITE setTaskFilesList NOTIFY taskFilesListChanged)
    Q_PROPERTY(QString curPrintFile READ getCurPrintFile WRITE setCurPrintFile NOTIFY curPrintFileChanged)

public:
    explicit MsgControl(QObject *parent = nullptr);
    ~MsgControl();

public:
    Q_INVOKABLE void publishMsg(const QString& msg);

    Q_INVOKABLE void motorMoveForward(bool);     //向前
    Q_INVOKABLE void motorMoveBack(bool);        //向后
    Q_INVOKABLE void motorMoveLeft(bool);        //向左
    Q_INVOKABLE void motorMoveRight(bool);       //向右
    Q_INVOKABLE void motorMoveOrigin();          //回原点

    Q_INVOKABLE void startPrint(int);  //开始打印
    Q_INVOKABLE void pausePrint();     //暂停打印
    Q_INVOKABLE void resumePrint();    //继续打印
    Q_INVOKABLE void cancelPrint();    //停止打印
    Q_INVOKABLE void clean();          //清洗
    Q_INVOKABLE void testPrint();      //测试

    Q_INVOKABLE void getUSB_FileDir();    //获取挂载USB的文件
    Q_INVOKABLE void getWifi_FileDir();   //获取挂载Wifi的文件
    Q_INVOKABLE void getNext_DirInfo(const QString& name);     //获取下一级目录下的信息
    Q_INVOKABLE void setRipMode(const QString& mode);          //设置打印模式
    Q_INVOKABLE void selectPrintFile(const QString& filePath); //选择打印文件
    Q_INVOKABLE void getUnPrintFiles(); //获取当前目录下的等待打印的文件
    Q_INVOKABLE void getPrintWorkList(); //获取添加的任务列表
    Q_INVOKABLE void addPrintWork(const float&,const float&,const QString&,const QString&); //添加打印任务
    Q_INVOKABLE void removePrintWork(const QString& uuid); //删除打印任务

private:
    void getRipMode();   //获取板卡打印rip模式列表
    QString getPrintDpi(int modeId);
    void getSmallPic(); //请求获取缩略图
    void getPicinfo(const QString& filePath, const QString& uuid); //获取待打印图片实际信息
    void addCurPrintWork(const float&,const float&,const QString&,const QString&);

private:
    void dealCallStartPrint(const Json::Value&);  //处理开始打印
    void dealCallPausePrint(const Json::Value&);  //处理暂停打印
    void dealCallResumePrint(const Json::Value&); //处理继续打印
    void dealCallCancelPrint(const Json::Value&); //处理继续打印
    void dealCallClean(const Json::Value&);       //处理清洗
    void dealCallTest(const Json::Value&);        //处理测试打印
    void dealCallGoorg(const Json::Value&);       //处理小车回原点
    void dealCallRootDirList(const Json::Value&); //获取根目录盘符文件以及文件夹
    void deaCallGetFileList(const Json::Value&);  //处理获取文件列表
    void dealCallGetRipMode(const Json::Value&);  //处理获取的ripmode列表
    void dealCallPicinfo(const Json::Value&);     //处理待打印图片实际信息
    void dealCallAddPrintList(const Json::Value&); //处理添加打印任务
    void dealCallPrintWorkList(const Json::Value&); //处理服务端返回的任务列表
    void dealCallRemovePrintWork(const Json::Value&); //处理删除打印任务
    void dealCallPrintProgress(const Json::Value&);   //处理打印进度
    void dealCallRipProgress(const Json::Value&);  //处理rip状态反馈
    void dealCallWarnMessage(const Json::Value&);  // 处理错误信息反馈

signals:
    void startBtnStatusChanged();
    void errorMsgChanged();
    void netConnectedChanged();
    void fileListChanged();
    void onAddImage(const QString &id, const QImage &image);
    void curFileslistChanged();
    void taskFilesListChanged();
    void curPrintFileChanged();

public slots:
    void doCallBack(const QString& msg);            //获取服务端返回的消息
    void doCallBinaryBack(const QByteArray& data);  //获取服务端缩略图bateArray
    void doNetConnect(const bool&);                 //socket client连接状态

public:
    int getStartBtnStatus();
    void setStartBtnStatus(int);
    QVariantMap getErrorMsg();
    void setErrorMsg(const QVariantMap&);
    bool getNetConnected();
    QVariantList getFileList();
    void setFileList(const QVariantList&);

    void setCurFilesList(const QVariantList&);
    QVariantList getCurFilesList();
    void setTaskFilesList(const QVariantList&);
    QVariantList getTaskFilesList();

    QString getCurPrintFile();
    void setCurPrintFile(const QString& fileName);

private:
    std::shared_ptr<DoDataThread> m_DoDataThread;  //处理socket消息的线程
    int m_StartBtnStatus = 1;                      //打印的状态
    bool m_NetConnected = false;                   //服务端的连通状态
    int m_RipMode = 0;                             //当前的ripmode模式

    QVariantMap m_ErrorMsg = {{"flag",true},{"msg"," "},{"type"," "}};  //服务端返回的异常消息
    QVariantList m_FileList = {};                  //缓存文件以及文件夹
    QVariantList m_RipModeList = {};               //缓存ripmode列表
    QVariantMap m_CurPrintWorkMap = {};            //当前的待打印任务数据

    QVariantList m_UnPrintFiles = {};   //当前的目录的下所有文件 "file" 不包括文件夹
    QVariantList m_TaskPrintFiles = {}; //从服务端获取的打印任务列表

    QString m_CurPrintFile = "";//预览页面显示
};

#endif // DEALMSGPACKET_H
